<?php
namespace Admin\Controller;
use Think\Controller;
use Common\Container\Container;
use Admin\Model\AuthRuleModel;
class AdminController extends Container {

    /**
     * 前台静态提醒
     * @var array
     */
    public $alert = ['status'=>0,'msg'=>'','data'=>null];

    /**
     * 后台控制器初始化操作
     */
    public function _initialize(){

        parent::_initialize();

        // 获取当前用户ID
        if(defined('UID')) return ;
        define('UID',is_login());
        if( !UID ){// 还没登录 跳转到登录页面
            $this->redirect('Public/login');
        }
        trace(session('user_auth'),'user_auth');
        //读取数据库中的配置
        $config     =   null;//S("DB_CONFIG");
        if(!$config){
            $Config     =   new \Common\Tool\Config();
            $config =   $Config::lists();//解析的配置数据
            trace($config,'config');
            S('DB_CONFIG',$config);
        }
        C($config);

        // 是否是超级管理员
        define('IS_ROOT',   is_administrator());
        // 检测系统权限
        if(!IS_ROOT){
            $rule  = strtolower(MODULE_NAME.'/'.CONTROLLER_NAME.'/'.ACTION_NAME);
            $access =   $this->accessControl($rule);
            if ( false === $access ) {
                $this->error('403:禁止访问');
					exit;
            }elseif(null === $access ){
                //检测访问权限
                if ( !$this->checkRule($rule,array('in','1,2')) ){
                    $this->error('未授权访问!');
					exit;
                }else{
                    // 检测分类及内容有关的各项动态权限
                    $dynamic    =   $this->checkDynamic();
                    if( false === $dynamic ){
                        $this->error('未授权访问!');
						exit;
                    }
                }
            }
        }


        return null;
    }

    public function alert($status = 0, $msg = '', $data = null){
        $this->alert['status'] = $status?:$this->alert['status'];
        $this->alert['sg'] = $msg?:$this->alert['msg'];
        $this->alert['data'] = $data?:$this->alert['data'];
        $this->assign('alert',$this->alert);
    }

    /**
     * 检测是否是需要动态判断的权限
     * @return boolean|null
     *      返回true则表示当前访问有权限
     *      返回false则表示当前访问无权限
     *      返回null，则表示权限不明
     *
     */
    protected function checkDynamic(){}

    /**
     * 返回后台节点数据
     * @param boolean $tree    是否返回多维数组结构(生成菜单时用到),为false返回一维数组(生成权限节点时用到)
     * @retrun array
     *
     * 注意,返回的主菜单节点数组中有'controller'元素,以供区分子节点和主节点
     *
     */
    final protected function returnNodes($tree = true){
        static $tree_nodes = array();
        if ( $tree && !empty($tree_nodes[(int)$tree]) ) {
            return $tree_nodes[$tree];
        }
        // 是否返回多维数组
        if((int)$tree){
            // 获取全部菜单列表
            $list = $this['Menu']->get([], 'id,pid,title,url,tip,hide', 'sort asc');
            foreach ($list as $key => $value) {
                // 如果url中没有模块名称，则拼接模块名称
                if( stripos($value['url'],MODULE_NAME)!==0 ){
                    $list[$key]['url'] = MODULE_NAME.'/'.$value['url'];
                }
            }
            // 把菜单列表转为树形结构
            $nodes = list_to_tree($list,$pk='id',$pid='pid',$child='operator',$root=0);
            foreach ($nodes as $key => $value) {
                // 把主菜单的子菜单索引设置为'child'
                if(!empty($value['operator'])){
                    $nodes[$key]['child'] = $value['operator'];
                    unset($nodes[$key]['operator']);
                }
            }
        }else{
            // 获取全部菜单列表
            $nodes = $this['Menu']->get([], 'title,url,tip,pid', 'sort asc');
            // 如果url中没有模块名称，则拼接模块名称
            foreach ($nodes as $key => $value) {
                if( stripos($value['url'],MODULE_NAME)!==0 ){
                    $nodes[$key]['url'] = MODULE_NAME.'/'.$value['url'];
                }
            }
        }
        $tree_nodes[(int)$tree]   = $nodes;
        return $nodes;
    }


    /**
     * 容器
     *
     * @var mixed
     */
    static $container = null;

    /**
     * 获取容器内的实例，若不存在则尝试创建
     *
     * @param $abstract
     * @return mixed
     */
    static function container($abstract){

        static::$container[$abstract] = static::$container[$abstract]?:D($abstract);

        if ( static::$container[$abstract] ) {
            return static::$container[$abstract];
        } else {
            return null;
        }
    }


    /**
     * action访问控制,在 **登陆成功** 后执行的第一项权限检测任务
     *
     * @return boolean|null  返回值必须使用 `===` 进行判断
     *
     *   返回 **false**, 不允许任何人访问(超管除外)
     *   返回 **true**, 允许任何管理员访问,无需执行节点权限检测
     *   返回 **null**, 需要继续执行节点权限检测决定是否允许访问
     */
    final protected function accessControl($check = null){
        $allow = C('ALLOW_VISIT');
        $deny  = C('DENY_VISIT');
        $check || $check = strtolower(CONTROLLER_NAME.'/'.ACTION_NAME);
        if ( !empty($deny)  && in_array_case($check,$deny) ) {
            return false;//非超管禁止访问deny中的方法
        }

        if ( !empty($allow) && in_array_case($check,$allow) ) {
            return true;
        }
        return null;//需要检测节点权限
    }

    /**
     * 获取控制器菜单数组,二级菜单元素位于一级菜单的'_child'元素中
     */
    final public function getMenus($controller=CONTROLLER_NAME){
//        $menus  =   session('ADMIN_MENU_LIST.'.$controller);
        if(empty($menus)){
            // 获取主菜单
            $where['pid']   =   0;
            $where['hide']  =   0;
            $where['status'] = 1;
            if(!C('DEVELOP_MODE')){ // 是否开发者模式
                $where['is_dev']    =   0;
            }
            $menus['main']  =   M('Menu')->where($where)->order('sort asc')->field('id,title,url')->select();
            $menus['child'] =   array(); //设置子节点

            // 判断主菜单权限
            foreach ($menus['main'] as $key => $item) {
                if ( !IS_ROOT && !$this->checkRule(strtolower(MODULE_NAME.'/'.$item['url']),AuthRuleModel::RULE_MAIN,null) ) {
                    unset($menus['main'][$key]);
                    continue;//继续循环
                }
//                if(strtolower(CONTROLLER_NAME.'/'.ACTION_NAME)  == strtolower($item['url'])){
//                    $menus['main'][$key]['class']='current';
//                }
            }

            // 获取子菜单
            $where_child['pid']   =   array('gt',0);
            $where_child['hide']  =   0;
            if(!C('DEVELOP_MODE')){ // 是否开发者模式
                $where_child['is_dev']    =   0;
            }
            $child_list  =   M('Menu')->where($where_child)->order('sort asc')->field('id,pid,title,url')->select();

            // 检测菜单权限
            foreach ($child_list as $key=>$value) {
                if( stripos($value['url'],MODULE_NAME)!==0 ){
                    $rule = MODULE_NAME.'/'.$value['url'];
                }else{
                    $rule = $value['url'];
                }
                if( IS_ROOT || $this->checkRule($rule, AuthRuleModel::RULE_URL,null)) {
                    $menus['child'][] = $value;
                }
            }

            foreach($menus['main'] as $key=>$value){
                foreach( $menus['child'] as $v){
                    if ( $v['pid'] == $value['id'])
                        $menus['main'][$key]['child'][] = $v;
                }
            }
//            $pid = M('Menu')->where("pid !=0 AND url like '%{$controller}/".ACTION_NAME."%'")->getField('pid');
//            if($pid){
//                // 查找当前主菜单
//                $nav =  M('Menu')->find($pid);
//                if($nav['pid']){
//                    $nav    =   M('Menu')->find($nav['pid']);
//                }
//                foreach ($menus['main'] as $key => $item) {
//                    // 获取当前主菜单的子菜单项
//                    if($item['id'] == $nav['id']){
//                        $menus['main'][$key]['class']='current';
//                        //生成child树
//                        $groups = M('Menu')->where(array('group'=>array('neq',''),'pid' =>$item['id']))->distinct(true)->getField("group",true);
//                        //获取二级分类的合法url
//                        $where          =   array();
//                        $where['pid']   =   $item['id'];
//                        $where['hide']  =   0;
//                        if(!C('DEVELOP_MODE')){ // 是否开发者模式
//                            $where['is_dev']    =   0;
//                        }
//                        $second_urls = M('Menu')->where($where)->getField('id,url');
//
//                        if(!IS_ROOT){
//                            // 检测菜单权限
//                            $to_check_urls = array();
//                            foreach ($second_urls as $key=>$to_check_url) {
//                                if( stripos($to_check_url,MODULE_NAME)!==0 ){
//                                    $rule = MODULE_NAME.'/'.$to_check_url;
//                                }else{
//                                    $rule = $to_check_url;
//                                }
//                                if($this->checkRule($rule, AuthRuleModel::RULE_URL,null))
//                                    $to_check_urls[] = $to_check_url;
//                            }
//                        }
//                        // 按照分组生成子菜单树
//                        foreach ($groups as $g) {
//                            $map = array('group'=>$g);
//                            if(isset($to_check_urls)){
//                                if(empty($to_check_urls)){
//                                    // 没有任何权限
//                                    continue;
//                                }else{
//                                    $map['url'] = array('in', $to_check_urls);
//                                }
//                            }
//                            $map['pid']     =   $item['id'];
//                            $map['hide']    =   0;
//                            if(!C('DEVELOP_MODE')){ // 是否开发者模式
//                                $map['is_dev']  =   0;
//                            }
//                            $menuList = M('Menu')->where($map)->field('id,pid,title,url,tip')->order('sort asc')->select();
//                            $menus['child'][$g] = list_to_tree($menuList, 'id', 'pid', 'operater', $item['id']);
//                        }
//                    }
//                }
//            }
//            session('ADMIN_MENU_LIST.'.$controller,$menus);
        }
        return $menus;
    }



    /**
     * 权限检测
     * @param string  $rule    检测的规则
     * @param string  $mode    check模式
     * @return boolean
     */
    final protected function checkRule($rule, $type=AuthRuleModel::RULE_URL, $mode='url'){
        static $Auth    =   null;
        if (!$Auth) {
            $Auth       =   new \Think\Auth();
        }
        if(!$Auth->check($rule,UID ,$type,$mode)){
            return false;
        }
        return true;
    }

}
